﻿using ImageControl.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using ImageControl.Models;

namespace ImageControl.ViewModels
{
    public abstract class HandlerViewModel : BindableBase, ICapturable
    {
        public const double StandartHandlerSize = 10;
        static readonly SolidColorBrush ReleasedColor = new SolidColorBrush(Colors.Transparent);
        static readonly SolidColorBrush HoveredColor = new SolidColorBrush(Colors.Red);
        static readonly SolidColorBrush CapturedColor = new SolidColorBrush(Colors.Yellow);

        private double width;
        private double height;
        private Point topLeft;
        private SolidColorBrush background;

        public AdornerViewModel Adorner { get; private set; }

        public SolidColorBrush Background
        {
            get
            {
                return this.background;
            }
            set
            {
                this.SetProperty(ref this.background, value, "Background");
            }
        }

        public double Width
        {
            get
            {
                return this.width;
            }
            set
            {
                this.SetProperty(ref this.width, value, "Width");
            }
        }

        public double Height
        {
            get
            {
                return this.height;
            }
            set
            {
                this.SetProperty(ref this.height, value, "Height");
            }
        }

        public Point TopLeft
        {
            get
            {
                return this.topLeft;
            }
            set
            {
                this.SetProperty(ref this.topLeft, value, "TopLeft");
            }
        }

        public HandlerViewModel(AdornerViewModel adorner)
        {
            this.Adorner = adorner;

            this.width = StandartHandlerSize;
            this.height = StandartHandlerSize;
            this.topLeft = new Point();
            this.ReleaseHover();
        }

        public void Hover()
        {
            this.Background = HandlerViewModel.HoveredColor;
        }

        public bool ShouldHandle(Point coordinate)
        {
            return
                coordinate.X.IsBetween(this.TopLeft.X, this.TopLeft.X + this.Width) &&
                coordinate.Y.IsBetween(this.TopLeft.Y, this.TopLeft.Y + this.Height);
        }


        public void ReleaseHover()
        {
            this.Background = HandlerViewModel.ReleasedColor;
        }

        public void Capture(Point coordinate)
        {
            this.Background = HandlerViewModel.CapturedColor;
        }

        public abstract void HandleMove(Point coordinate);

        protected void HandleMove(double orientedWidth, double orientedHeight, double rotatedCenterX, double rotatedCenterY)
        {
            Point imageTopLeft = this.CalculateNewImageTopLeft(
                orientedWidth, orientedHeight, rotatedCenterX, rotatedCenterY);

            this.Adorner.ImageModel = new ImageModel(
                orientedWidth,
                orientedHeight,
                this.Adorner.ImageModel.Rotation,
                imageTopLeft);
        }

        private Point CalculateNewImageTopLeft(double orientedWidth, double orientedHeight, double rotatedCenterX, double rotatedCenterY)
        {
            Point rotatedCenter = new Point(rotatedCenterX, rotatedCenterY);
            Point center = this.Adorner.GetDocumentCoordinateFromRotatedPoint(rotatedCenter);

            return new Point(center.X - orientedWidth / 2, center.Y - orientedHeight / 2);
        }

        protected void HandleRightMove(Point coordinate, out double orientedWidth, out double rotatedCenterX)
        {
            orientedWidth = this.Adorner.GetRotatedCoordinateFromDocumentPoint(coordinate).X;
            rotatedCenterX = orientedWidth / 2;
        }

        protected void HandleBottomMove(Point coordinate, out double orientedHeight, out double rotatedCenterY)
        {
            orientedHeight = this.Adorner.GetRotatedCoordinateFromDocumentPoint(coordinate).Y;
            rotatedCenterY = orientedHeight / 2;
        }

        protected void HandleLeftMove(Point cooridinate, out double orientedWidth, out double rotatedCenterX)
        {
            double deltaX = this.Adorner.GetRotatedCoordinateFromDocumentPoint(cooridinate).X;
            orientedWidth = this.Adorner.ImageModel.OrientedWidth - deltaX;
            rotatedCenterX = (this.Adorner.ImageModel.OrientedWidth + deltaX) / 2;
        }

        protected void HandleTopMove(Point coordinate, out double orientedHeight, out double rotatedCenterY)
        {
            double deltaY = this.Adorner.GetRotatedCoordinateFromDocumentPoint(coordinate).Y;
            orientedHeight = this.Adorner.ImageModel.OrientedHeight - deltaY;
            rotatedCenterY = (this.Adorner.ImageModel.OrientedHeight + deltaY) / 2;
        }

        public void ReleaseCapture()
        {
            this.Background = HandlerViewModel.ReleasedColor;
        }
    }
}
